/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;


import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.comac.ins.common.core.constant.CommonConstant;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.isfd.constant.enums.IsfdStructureDefinitionTreeLevelEnum;
import com.comac.ins.isfd.constant.enums.PartFileLevelEnum;
import com.comac.ins.isfd.constant.enums.PartFileTypeEnum;
import com.comac.ins.isfd.domain.IsfdModelManagementCalculateRefNecessaryItems;
import com.comac.ins.isfd.domain.IsfdModelManagementNecessaryItems;
import com.comac.ins.isfd.domain.bo.IsfdModelManagementNecessaryItemsBo;
import com.comac.ins.isfd.domain.bo.IsfdModelManagementPartBo;
import com.comac.ins.isfd.domain.bo.IsfdModelManagementStructureDefinitionTreeBo;
import com.comac.ins.isfd.domain.bo.query.IsfdModelManagementNecessaryItemsQueryBo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.mapper.IsfdModelManagementCalculateFileMapper;
import com.comac.ins.isfd.mapper.IsfdModelManagementCalculateRefNecessaryItemsMapper;
import com.comac.ins.isfd.mapper.IsfdModelManagementNecessaryItemsMapper;
import com.comac.ins.isfd.mapper.IsfdModelManagementTaskMapper;
import com.comac.ins.isfd.service.IIsfdModelManagementNecessaryItemsService;
import com.comac.ins.isfd.service.IIsfdModelManagementPartService;
import com.comac.ins.isfd.service.IIsfdModelManagementStructureDefinitionTreeService;
import com.comac.ins.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 必备件库Service业务层处理
 *
 * @author Lion Li
 * @date 2024-08-19
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class IsfdModelManagementNecessaryItemsServiceImpl implements IIsfdModelManagementNecessaryItemsService {

    @Autowired
    private IsfdModelManagementNecessaryItemsMapper baseMapper;
    @Autowired
    private IsfdModelManagementCalculateRefNecessaryItemsMapper isfdModelManagementCalculateRefNecessaryItemsMapper;
    @Autowired
    private IsfdModelManagementCalculateFileMapper isfdModelManagementCalculateFileMapper;
    @Autowired
    private IsfdModelManagementTaskMapper isfdModelManagementTaskMapper;
    @Autowired
    private IIsfdModelManagementStructureDefinitionTreeService iIsfdModelManagementStructureDefinitionTreeService;
    @Autowired
    private IIsfdModelManagementPartService iIsfdModelManagementPartService;
    @Autowired
    private ISysDictDataService iSysDictDataService;

    /**
     * 查询必备件库
     *
     * @param id 主键
     * @return 必备件库
     */
    @Override
    public IsfdModelManagementNecessaryItemsVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    public List<IsfdModelManagementStructureDefinitionTreeNodeVo> listTree() {
        // 查询总的树结构 机型-部段
        List<IsfdModelManagementStructureDefinitionTreeNodeVo> treeNodeVos = iIsfdModelManagementStructureDefinitionTreeService.queryListTree();

        // 找出部段和组件的节点，并查询必备件数量封装到梳理
        for (IsfdModelManagementStructureDefinitionTreeNodeVo treeNode : treeNodeVos) {
            findLeafNodesRecursive(treeNode, treeNode.getMark(), "");
        }
        return treeNodeVos;
    }

    @Override
    public List<IsfdModelManagementStructureDefinitionTreeNodeVo> getComponentList(String modelNumber, String batchNumber, String sectionNumber, Boolean needCount) {
        IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber);

        List<IsfdModelManagementStructureDefinitionTreeNodeVo> result = new ArrayList<>();
        //组件部分
        IsfdModelManagementPartBo isfdModelManagementPartBo = new IsfdModelManagementPartBo();
        isfdModelManagementPartBo.setModelNumber(modelNumber);
        isfdModelManagementPartBo.setBatchNumber(batchNumber);
        isfdModelManagementPartBo.setSectionNumber(sectionNumber);
        isfdModelManagementPartBo.setFileLevel(PartFileLevelEnum.COMPONENT.getValue());
        isfdModelManagementPartBo.setFileType(PartFileTypeEnum.PART.getValue());
        List<IsfdModelManagementPartVo> partList = iIsfdModelManagementPartService.queryList(isfdModelManagementPartBo);

        if (CollectionUtils.isNotEmpty(partList)) {
            // 去重
            Map<String, List<IsfdModelManagementPartVo>> componentMap = partList.stream()
                .collect(Collectors.groupingBy(IsfdModelManagementPartVo::getComponentNumber));

            for (String componentNumber : componentMap.keySet()) {
                // 左侧树需要计算，新增界面不需要计算
                IsfdModelManagementStructureDefinitionTreeNodeVo componentVo = new IsfdModelManagementStructureDefinitionTreeNodeVo();
                if (needCount != null && needCount) {
                    Long componentCount = baseMapper.selectCount(new LambdaQueryWrapper<IsfdModelManagementNecessaryItems>()
                        .eq(IsfdModelManagementNecessaryItems::getModelNumber, modelNumber)
                        .eq(IsfdModelManagementNecessaryItems::getBatchNumber, batchNumber)
                        .eq(IsfdModelManagementNecessaryItems::getSectionNumber, sectionNumber)
                        .eq(IsfdModelManagementNecessaryItems::getComponentNumber, componentNumber));
                    componentVo.setNecessaryItemsCount(componentCount);
                }

                componentVo.setParentId(sectionVo.getId());
                componentVo.setMark(componentNumber);
                componentVo.setName(componentNumber);
                componentVo.setQueryIndex(sectionVo.getQueryIndex() + "::" + componentNumber);
                result.add(componentVo);
            }
        }

        return result;
    }

    /**
     * 找出部段和组件的节点，并查询必备件数量封装到梳理
     */
    public void findLeafNodesRecursive(IsfdModelManagementStructureDefinitionTreeNodeVo node, String modelNumber, String parentMark) {
        if (node == null) {
            return;
        }
        if (node.getParentId() != 0) {
            if (IsfdStructureDefinitionTreeLevelEnum.BATCH_NO.getValue().equals(node.getLevel())) {
                String batchNumber = node.getMark();
                //部段部分
                Long sectionCount = baseMapper.selectCount(new LambdaQueryWrapper<IsfdModelManagementNecessaryItems>()
                    .eq(IsfdModelManagementNecessaryItems::getModelNumber, modelNumber)
                    .eq(IsfdModelManagementNecessaryItems::getBatchNumber, batchNumber));
                node.setNecessaryItemsCount(sectionCount);
            }
            if (IsfdStructureDefinitionTreeLevelEnum.SECTION.getValue().equals(node.getLevel())) {
                String sectionNumber = node.getMark();
                //部段部分
                Long sectionCount = baseMapper.selectCount(new LambdaQueryWrapper<IsfdModelManagementNecessaryItems>()
                    .eq(IsfdModelManagementNecessaryItems::getModelNumber, modelNumber)
                    .eq(IsfdModelManagementNecessaryItems::getBatchNumber, parentMark)
                    .eq(IsfdModelManagementNecessaryItems::getSectionNumber, sectionNumber));
                node.setNecessaryItemsCount(sectionCount);
            }
        }
        // 遍历子节点
        if (CollectionUtils.isNotEmpty(node.getChildren())) {
            for (IsfdModelManagementStructureDefinitionTreeNodeVo child : node.getChildren()) {
                findLeafNodesRecursive(child, modelNumber, node.getMark());
            }
        }
    }

    /**
     * 分页查询必备件库列表
     */
    @Override
    public TableDataInfo<IsfdModelManagementNecessaryItemsVo> queryPageList(IsfdModelManagementNecessaryItemsQueryBo bo) {
        List<String> sectionNumbers = null;
        List<String> selectSectionNumbers = new ArrayList<>();

        // 两个地方使用
        // 当入参有部段编号集合，是计算文件选择必备件的筛选场景
        // 当只有单个部段的时候，是必备家管理菜单界面场景
        if (CollectionUtils.isEmpty(bo.getSectionNumbers())) {
            if (StringUtils.isNotBlank(bo.getSectionName())) {
                IsfdModelManagementStructureDefinitionTreeBo treeBo = new IsfdModelManagementStructureDefinitionTreeBo();
                treeBo.setName(bo.getSectionName());
                List<IsfdModelManagementStructureDefinitionTreeVo> sectionTreeVoList = iIsfdModelManagementStructureDefinitionTreeService.queryList(treeBo);
                if (CollectionUtils.isEmpty(sectionTreeVoList)) {
                    return TableDataInfo.build();
                }
                sectionNumbers = sectionTreeVoList.stream().map(IsfdModelManagementStructureDefinitionTreeVo::getMark).toList();
            }

            if (CollectionUtils.isNotEmpty(sectionNumbers)) {
                selectSectionNumbers.addAll(sectionNumbers);
            }

            if (StringUtils.isNotBlank(bo.getSectionNumber())) {
                if (!selectSectionNumbers.contains(bo.getSectionNumber())) {
                    selectSectionNumbers.add(bo.getSectionNumber());
                }
            }
        } else {
            selectSectionNumbers = bo.getSectionNumbers();
        }


        LambdaQueryWrapper<IsfdModelManagementNecessaryItems> lqw = buildQueryWrapper(bo, selectSectionNumbers);

        // 根据 model_number 条件查询
        if (StringUtils.isNotBlank(bo.getModelNumber())) {
            lqw.eq(IsfdModelManagementNecessaryItems::getModelNumber, bo.getModelNumber());
        }

        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(bo.getPageNum());
        pageQuery.setPageSize(bo.getPageSize());
        Page<IsfdModelManagementNecessaryItemsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        result.getRecords().forEach(r -> {
            IsfdModelManagementStructureDefinitionTreeVo modelVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(r.getModelNumber(), null, null);
            r.setModelName(modelVo != null ? modelVo.getName() : null);

            if (StringUtils.isNotBlank(r.getBatchNumber())) {
                IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(r.getModelNumber(), r.getBatchNumber(), null);
                r.setBatchName(batchVo != null ? batchVo.getName() : null);
            }

            if (StringUtils.isNotBlank(r.getSectionNumber())) {
                IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(r.getModelNumber(), r.getBatchNumber(), r.getSectionNumber());
                r.setSectionName(sectionVo != null ? sectionVo.getName() : null);
            }
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的必备件库列表
     *
     * @param bo 查询条件
     * @return 必备件库列表
     */
    @Override
    public List<IsfdModelManagementNecessaryItemsVo> queryList(IsfdModelManagementNecessaryItemsBo bo) {
        LambdaQueryWrapper<IsfdModelManagementNecessaryItems> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public List<IsfdModelManagementNecessaryItemsVo> queryListByCalculateId(Long calculateId) {
        List<IsfdModelManagementCalculateRefNecessaryItems> isfdModelManagementCalculateRefNecessaryItems = isfdModelManagementCalculateRefNecessaryItemsMapper
            .selectList(new LambdaQueryWrapper<IsfdModelManagementCalculateRefNecessaryItems>()
                .eq(IsfdModelManagementCalculateRefNecessaryItems::getCalculateId, calculateId));
        if (CollectionUtils.isEmpty(isfdModelManagementCalculateRefNecessaryItems)) {
            return new ArrayList<>();
        }
        List<Long> necessaryItemIds = isfdModelManagementCalculateRefNecessaryItems.stream().map(IsfdModelManagementCalculateRefNecessaryItems::getNecessaryItemsId).toList();
        List<IsfdModelManagementNecessaryItemsVo> isfdModelManagementNecessaryItemsVos = baseMapper.selectVoBatchIds(necessaryItemIds);
        isfdModelManagementNecessaryItemsVos.forEach(r -> {
            IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(r.getModelNumber(), r.getBatchNumber(), null);
            r.setBatchName(batchVo != null ? batchVo.getName() : null);

            IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(r.getModelNumber(), r.getBatchNumber(), r.getSectionNumber());
            r.setSectionName(sectionVo != null ? sectionVo.getName() : null);
        });
        return isfdModelManagementNecessaryItemsVos;
    }

    @Override
    public Boolean save(MultipartFile multipartFile, String fullNumbers, String remark) throws IOException {
        String prefixPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_NECESSARY_ITEMS_DATA_PREFIX);
        if (StringUtils.isBlank(prefixPath)) {
            throw new BaseException("必备件存储路径前缀未配置，请到字典管理中配置，并重试.");
        }
        String[] fullNumberList = fullNumbers.split(",");
        List<IsfdModelManagementNecessaryItems> poList = new ArrayList<>();
        for (String fullNumber : fullNumberList) {
            IsfdModelManagementNecessaryItems po = new IsfdModelManagementNecessaryItems();
            String[] split = fullNumber.split("::");
            if (split.length < 2 || split.length > 4) {
                throw new BaseException("只允许在批次、部段和组件下添加必备件，请确认后重试！");
            }
            String modelNumber = split[0];
            String batchNumber = split[1];
            IsfdModelManagementStructureDefinitionTreeVo modelVo = iIsfdModelManagementStructureDefinitionTreeService
                .queryOneByQueryIndex(modelNumber, null, null);
            if (ObjectUtils.isNull(modelVo)) {
                throw new BaseException("选择的机型【" + modelNumber + "】不存在，请确认后重试.");
            }
            IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService
                .queryOneByQueryIndex(modelNumber, batchNumber, null);
            if (ObjectUtils.isNull(batchVo)) {
                throw new BaseException("选择的批次【" + batchNumber + "】不存在，请确认后重试.");
            }
            if (split.length >= 3) {
                String sectionNumber = split[2];
                IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService
                    .queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber);
                if (sectionVo == null) {
                    throw new BaseException("选择的部段【" + sectionNumber + "】不存在，请确认后重试.");
                }
                po.setSectionNumber(sectionNumber);
                if (split.length == 4) {
                    String componentNumber = split[3];
                    po.setComponentNumber(componentNumber);
                }
            }

            po.setModelNumber(modelNumber);
            po.setBatchNumber(batchNumber);
            po.setRemark(remark);
            poList.add(po);
        }

        for (IsfdModelManagementNecessaryItems po : poList) {
            // 2.文件操作
            long id = IdUtil.getSnowflakeNextId();
            String fileName = multipartFile.getOriginalFilename();
            String filePath = prefixPath + po.getBatchNumber() + "/" + id;
            String fileUrl = filePath + "/" + fileName;
            Path targetPath = Paths.get(fileUrl);
            File dir = targetPath.getParent().toFile();
            if (!dir.exists()) {
                dir.mkdirs();
            }
            Files.write(targetPath, multipartFile.getBytes());
            // 3.db操作
            po.setFileName(fileName);
            //保留5位小数
            String resultStr = String.format("%.5f", (double) multipartFile.getSize() / 1024);
            po.setFileSize(Double.parseDouble(resultStr));
            po.setFileUrl(fileUrl);
            po.setId(id);
            baseMapper.insert(po);
        }

        return Boolean.TRUE;
    }

    private LambdaQueryWrapper<IsfdModelManagementNecessaryItems> buildQueryWrapper(IsfdModelManagementNecessaryItemsQueryBo bo, List<String> selectSectionNumbers) {
        LambdaQueryWrapper<IsfdModelManagementNecessaryItems> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getModelNumber()), IsfdModelManagementNecessaryItems::getModelNumber, bo.getModelNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getBatchNumber()), IsfdModelManagementNecessaryItems::getBatchNumber, bo.getBatchNumber());
        lqw.in(CollectionUtils.isNotEmpty(selectSectionNumbers), IsfdModelManagementNecessaryItems::getSectionNumber, selectSectionNumbers);
        lqw.eq(StringUtils.isNotBlank(bo.getComponentNumber()), IsfdModelManagementNecessaryItems::getComponentNumber, bo.getComponentNumber());
        lqw.orderByDesc(IsfdModelManagementNecessaryItems::getCreateTime);
        return lqw;
    }

    private LambdaQueryWrapper<IsfdModelManagementNecessaryItems> buildQueryWrapper(IsfdModelManagementNecessaryItemsBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<IsfdModelManagementNecessaryItems> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getFileName()), IsfdModelManagementNecessaryItems::getFileName, bo.getFileName());
        lqw.eq(bo.getFileSize() != null, IsfdModelManagementNecessaryItems::getFileSize, bo.getFileSize());
        lqw.eq(StringUtils.isNotBlank(bo.getFileUrl()), IsfdModelManagementNecessaryItems::getFileUrl, bo.getFileUrl());
        lqw.eq(StringUtils.isNotBlank(bo.getModelNumber()), IsfdModelManagementNecessaryItems::getModelNumber, bo.getModelNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getBatchNumber()), IsfdModelManagementNecessaryItems::getBatchNumber, bo.getBatchNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getSectionNumber()), IsfdModelManagementNecessaryItems::getSectionNumber, bo.getSectionNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getComponentNumber()), IsfdModelManagementNecessaryItems::getComponentNumber, bo.getComponentNumber());
        return lqw;
    }


    /**
     * 校验并批量删除必备件库信息
     *
     * @param ids 待删除的主键集合
     * @return 是否删除成功
     */
    @Transactional
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids) {
        for (Long id : ids) {
            // 删除主表
            baseMapper.deleteById(id);
            // 删除和计算的关联关系表
            isfdModelManagementCalculateRefNecessaryItemsMapper.delete(new LambdaQueryWrapper<IsfdModelManagementCalculateRefNecessaryItems>()
                .eq(IsfdModelManagementCalculateRefNecessaryItems::getNecessaryItemsId, id));
        }
        return Boolean.TRUE;
    }

    @Override
    public String preDelete(Collection<Long> ids) {
        String result = null;
        for (Long id : ids) {
            // 查主表
            IsfdModelManagementNecessaryItems isfdModelManagementNecessaryItems = baseMapper.selectById(id);
            // 查询和计算的关联关系表
            List<IsfdModelManagementCalculateRefNecessaryItems> isfdModelManagementCalculateRefNecessaryItemList = isfdModelManagementCalculateRefNecessaryItemsMapper.selectList(new LambdaQueryWrapper<IsfdModelManagementCalculateRefNecessaryItems>()
                .eq(IsfdModelManagementCalculateRefNecessaryItems::getNecessaryItemsId, id));
            if (CollectionUtils.isNotEmpty(isfdModelManagementCalculateRefNecessaryItemList)) {
                for (IsfdModelManagementCalculateRefNecessaryItems isfdModelManagementCalculateRefNecessaryItems : isfdModelManagementCalculateRefNecessaryItemList) {
                    IsfdModelManagementCalculateFileVo isfdModelManagementCalculateFileVo = isfdModelManagementCalculateFileMapper.selectVoById(isfdModelManagementCalculateRefNecessaryItems.getCalculateId());
                    if (isfdModelManagementCalculateFileVo == null) {
                        continue;
                    }
                    IsfdModelManagementTaskVo isfdModelManagementTaskVo = isfdModelManagementTaskMapper.selectVoById(isfdModelManagementCalculateFileVo.getTaskId());
                    if (isfdModelManagementTaskVo == null) {
                        continue;
                    }
                    String taskName = isfdModelManagementTaskVo.getTaskName();
                    result = "文件名为：" + isfdModelManagementNecessaryItems.getFileName() + "的必备件，至少和模型组建任务为:" + taskName + "的计算存在关联关系，确认是否删除？";
                    break;
                }
            }
        }
        return result;
    }

    @Override
    public List<IsfdModelManagementNecessaryItemsVo> queryByBatchIds(List<Long> ids) {
        return baseMapper.selectVoBatchIds(ids);
    }
}
